package com.hxc.sercurity.configu;

import com.hxc.sercurity.filter.JwtAuthTokenFilter;
import com.hxc.sercurity.hander.AcessDeniedHanderImpl;
import com.hxc.sercurity.hander.AuthEnterExceptionHander;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.sql.DataSource;

/**
 * @author 韩先楚
 */
@Configuration
public class MyConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthTokenFilter jwtAuthTokenFilter;

    @Autowired
    private AuthEnterExceptionHander authEnterExceptionHander;

    @Autowired
    private AcessDeniedHanderImpl acessDeniedHander;

//    @Autowired
//    private UserDetailsService userDetailsService;
//
//    @Autowired
//    private DataSource dataSource;

//    @Bean
//    public PersistentTokenRepository persistentTokenRepository() {
//        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
//        jdbcTokenRepository.setDataSource(dataSource);
//        //自动创建表 也可以自动创建表 在源码里面 JdbcTokenRepositoryImpl 类中
////        jdbcTokenRepository.setCreateTableOnStartup(true);
//        return jdbcTokenRepository;
//    }

//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
////        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
////        String password = encoder.encode("123456");
////        auth.inMemoryAuthentication().withUser("hxc").password(password).roles();
//        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
//    }

//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        //配置自定义403页面
//        http.exceptionHandling().accessDeniedPage("/error403.html");
//
//        //退出登录
//        http.logout().logoutUrl("/logout").logoutSuccessUrl("/logout.html").permitAll();
//
//        http.formLogin()
//                .loginPage("/login.html")
//                .loginProcessingUrl("/sucess.html")
//                .defaultSuccessUrl("/sucess.html").permitAll()
//                .and().authorizeRequests()
//                //当前访问用户需要有admin访问权限才能访问 /index 只能判断一个权限
////                .antMatchers("/index").hasAuthority("adminss")
//                //当前访问用户需要有admin或user访问权限才能访问 /index 可以判断多个权限
////                .antMatchers("/index").hasAnyAuthority("admin", "user")
//                .antMatchers().permitAll()
//                .anyRequest().authenticated()
//                //jz: 记住我配置
//                .and().rememberMe()
//                .tokenRepository(persistentTokenRepository())
//                .tokenValiditySeconds(60 * 60 * 24 * 7)
//                .userDetailsService(userDetailsService)
//                .and().csrf().disable();
//    }
//


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                // 禁用CSRF保护
                .csrf().disable()
                // 设置会话管理策略为无状态
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                // 配置授权请求
                .authorizeRequests()
                // 允许匿名访问/login02路径
                //认证成功不可以访问,认证失败可以访问,用于登录接口
                //.permitAll()不是无论有没有在过滤器中认证成功,都放行
                //能不能认证关键在JwtAuthTokenFilter中(本项目自定义过滤器)
                .antMatchers("/login02").anonymous()
                //常用于静态资源的放行,这样不需要认证都能访问到
                .antMatchers("/res/**").permitAll()
                // 其他请求都需要进行身份验证
                .anyRequest().authenticated();
       //   添加JWT过滤器
        http.addFilterBefore(jwtAuthTokenFilter, UsernamePasswordAuthenticationFilter.class);

        //配置自定义的认证授权失败异常处理器
        //让过滤器链使用自定义的认证授权失败异常处理器
        http.exceptionHandling().accessDeniedHandler(acessDeniedHander);
        http.exceptionHandling().authenticationEntryPoint(authEnterExceptionHander);

        //允许跨域
        http.cors();
    }


    //用于登录接口使用AuthenticationManager的对象的方法authenticationManager.authenticate(auth);
    //使用这个方法来调用自定义UserDetailService(MyDetailService)重谢的方法loadUserByUsername() 来验证用户
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
//设置密码编译器
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
